﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using WorkStation.Frameworks.Core;
using WorkStation.Frameworks.Core.Extensions;
using WorkStation.Frameworks.Configuration;
using WorkStation.Frameworks.EasyBus;
using WorkStation.Frameworks.EasyBus.DbModel;
using WorkStation.Frameworks.EasyBus.Configurations;

namespace WorkStation.Frameworks.EasyBus.Configurations
{
    /// <summary>
    /// 配置文件配置提供器
    /// </summary>
    public class FileConfigProvider : IConfigProvider
    {
        protected BusConfiguration _config = null;
        protected string _configKey = string.Empty;

        public IBus Bus { get; set; }

        public BusConfiguration Config 
        {
            get 
            {
                Interlocked.CompareExchange<BusConfiguration>(ref this._config, ConfigurationManager.GetConfiguration<EasyBusSettingConfiguration>(this._configKey).Change(v => v.BusCollection.FirstOrDefault(c => c.Name.Equals(this.Bus.Name) && c.NodeName.Equals(this.Bus.NodeName))), null);

                if (this._config == null) 
                {
                    throw new EasyBusException("BusName:{0}，NodeName:{1}不在给定的配置文件中".Fmt(Bus.Name, Bus.NodeName));
                }

                Bus.DataBag["EasyBus.Endpoints"] = this._config.EndpointCollection.Endpoints.ToDictionary(v => v.Name, v => v.Value);

                return this._config;
            }
        }

        public FileConfigProvider(string configKey) 
        {
            this._configKey = configKey;
        }

        public IEnumerable<PublishInfo> GetPublishInfo()
        {
            return this.Config.PublishCollection.Publishs.Select(v => 
                new PublishInfo() 
                { 
                    BusName = this.Bus.Name, 
                    NodeName = this.Bus.NodeName, 
                    ServerIp = (this.Bus as IBusDataManager).Ip, 
                    RouteKey = v.RouteKey, 
                    Description = v.Description 
                }
            );
        }

        public IEnumerable<SubscribeInfo> GetSubscribeInfo()
        {
            return this.Config.SubscribeCollection.Subscribes.Select(v => 
                new SubscribeInfo() 
                {
                    BusName = this.Bus.Name,
                    NodeName = this.Bus.NodeName,
                    Description = v.Description,
                    Name = v.Name,
                    RouteKey = v.RouteKey,
                    PubBusName = v.BusName,
                    SubServerIp = (this.Bus as IBusDataManager).Ip,
                    Mq = this.Config.EndpointCollection[v.EndpointName].Value
                }
            );
        }

        public IEnumerable<ListenerInfo> GetListenerInfo()
        {
            return this.Config.SubscribeCollection.Subscribes.Select(v =>
                new ListenerInfo()
                {
                    Name = "{0}-Listener".Fmt(v.Name),
                    NodeName = this.Bus.NodeName,
                    SubBusName = this.Bus.Name,
                    ProcessThreadCount = v.ListenerConfig.ProcessThreadCount,
                    Mq = this.Config.EndpointCollection[v.EndpointName].Value,
                    Process = new ProcessInfo() { RouteKey = v.RouteKey, HandleName = v.ListenerConfig.Handles.Select(h => h.Name).ToArray() }
                }
            );
        }
    }
}
